2023/12/234356字符

手写 Promise

方式一:类

const MyPromise = (() => {
    const PENDING = 'pending',
        PESOLVED = 'resolved',
        PEJECTED = 'rejected',
        PromiseValue = Symbol('PromiseValue'),  // 状态数据
        PromiseStatus = Symbol('PromiseStatus'),  // 当前状态
        thenables = Symbol('thenables'),
        catchables = Symbol('catchables'),
        changeStatus = Symbol('changeStatus'),
        settleHandle = Symbol('settleHandle');  // 后续处理函数
    
    return class {
        constructor (executor) {
            this[PromiseStatus] = PENDING;
            this[PromiseValue] = undefined;
            this[thenables] = [];  // 后续处理函数数组 -> resolved
            this[catchables] = [];  // 后续处理函数数组 -> rejected

            const resolve = data => {
                this[changeStatus](PESOLVED, data, this[thenables]);
            }
            const reject = reason => {
                this[changeStatus](PEJECTED, reason, this[catchables]);
            }

            try {  // 捕获错误后返回
                executor(resolve, reject);
            } catch (err) {
                reject(err);
            }
        }
        [changeStatus] (newStatus, newValue, queue) {
            if (this[PromiseStatus] !== PENDING) {  // 状态无法变更
                return;
            }
            this[PromiseStatus] = newStatus;
            this[PromiseValue] = newValue;

            // 执行相应队列中的函数
            queue.forEach(handler => handler(newValue))
        }
        /**
         * @param {} handler 后续处理函数
         * @param {} immediatelyStatus 需要立即执行的状态
         * @param {} queue 作业队列
         */
        [settleHandle] (handler, immediatelyStatus, queue) {
            if (typeof handler !== 'function') {
                return;
            }
            if (this[PromiseStatus] === immediatelyStatus) {
                setTimeout(() => {
                    handler(this[PromiseStatus]);
                }, 0);
            } else {
                queue.push(handler);
            }
        }

        then (thenable, catchable) {
            this[settleHandle](thenable, PESOLVED, this[thenables]);
            this.catch(catchable);
        }

        catch (catchable) {
            this[settleHandle](catchable, PEJECTED, this[catchables]);
        }
    }
})();


const pro = new MyPromise((res, rej) => {
    // throw 1;
    res(1);
})
pro.then(res => {
    console.log(res);
})
pro.catch(err => {
    console.log(err);
})
console.log(pro);

方式二:构造函数

function Promise(callback) {
    const pending = 'pending';
    const fulfilled = 'fulfilled';
    const rejected = 'rejected';
    // 当前状态
    this.state = pending;
    // 当前值
    this.value = null;
    // 失败原因
    this.reason = null;
    // 成功和失败数组对象
    this.fulfilledCallback = [];
    this.rejectedCallback = [];

    // 成功处理
    this.resolve = (data) => {
        setTimeout(() => {
            if (this.state == pending) {
                this.state = fulfilled;
                this.value = data;
                this.fulfilledCallback.map(fn=>fn(this.value));
            }
        })
    }
    // 失败处理
    this.reject = (reason) => {
        setTimeout(() => {
            if (this.state == pending) {
                this.state = rejected;
                this.reason = reason;
                this.rejectedCallback.map(fn=>fn(this.reason));
            }
        })
    }
    // 捕获成功和失败,扔到成功和失败数组
    this.then = function(succesFn, errorFn) {
        this.fulfilledCallback.push(succesFn);
        this.rejectedCallback.push(errorFn);
    }
    // 捕获异常,直接扔到异常数组中
    this.catch = (errorFn) => {
        this.rejectedCallback.push(errorFn);
    }
    // 默认需要执行一次resolve和reject
    callback(this.resolve,this.reject);
}

// 验证结果
new Promise((resolve,reject) => {
    setTimeout(() => {
        resolve(10);
    },1000)
}).then((res) => {
    console.log(res);
},(err) => {
    console.log(err);
})